
from libs.comps.common.component import manager , TComponent
from libs.comps.common.compDB import TCompDB
from libs.comps.common.compKV import TCompKV
from libs.comps.common.compMqClient__ import TCompMqClient
from libs.utils.ice645_utils import TUtils645
import time
import threading
import os

class TDtuMq645 ( TCompMqClient):
    def __init__(self , _manager):
        super().__init__(_manager)
        self.info={
            "dtus":{},
            "variants":{}
        }
        self.sendBytes ={}
    @property
    def db(self):
        res: TCompDB= None
        try:
            dbCode = self.compSettings['dbCode']
            res = self.manager.getComp("TCompDB" , dbCode)
        except Exception as er :
            self.manager.log(self , er)
        return res
    @property
    def kv(self):
        res: TCompKV= None
        try:
            code = self.compSettings['compKvCode']
            res = self.manager.getComp("TCompKV" , code)
        except Exception as er :
            self.manager.log(self , er)
        return res



    def loadTask(self):
        res ={
            "status":0
        }
        try:
            mqSvrCode = self.compSettings['mqSvrCode']
            taskRes = self.db.queryByKey('iot/dtumq645/tasks',{"mqSvrCode": mqSvrCode})
            if taskRes['queryStatus'] == 1 :
                tasks = taskRes['datasetList'][0]
                for item in tasks:
                    dtuCode = item['dtuCode']
                    item['lastTime'] = 0
                    self.info['dtus'][dtuCode] = item
                vars = taskRes['datasetList'][1]
                for var in vars:
                    vk = f"{var['meterCode']}_{var['varCode']}"
                    self.info['variants'][vk] = var

                res['status']=1
        except Exception as er:
            self.manager.log(self , er)
        return res
    def sendMsgs(self ):
        try:
            for dtu in self.info['dtus'].values():
                dlt  = time.time() - dtu['lastTime']
                if  dlt> 3 :
                    try:
                        dtu['lastTime'] = time.time()
                        dtuCode = dtu['dtuCode']
                        topic = dtu['downTopic']
                        taskPath = f"{self.compSettings['taskPath']}/{dtuCode}"
                        if os.path.exists(taskPath):
                            taskFns = os.listdir(taskPath)
                            if len(taskFns)>0:
                                taskFn = taskFns[0]
                            #for taskFn in taskFns:
                                data = (taskFn[:-5]).split("_")
                                meterCode = data[1]
                                varCode = data[2]

                                key = f"{meterCode}_{varCode}"
                                if key not in self.sendBytes.keys():
                                    self.sendBytes[key] = TUtils645.encode645(meterCode , varCode)
                                sendBytes = self.sendBytes[key]
                                self.client.publish(topic , sendBytes)
                                fullFn = os.path.join(taskPath , taskFn)
                                os.remove(fullFn)
                    except Exception as erMq :
                        self.manager.log(self , erMq)
        except Exception as er:
            self.manager.log(self , er)

    def onMessage(self , message, mqttClient):
        try:
            topic = message.topic
            payload = message.payload
            if len(payload)> 10:
                msgInfo = TUtils645.decode645(payload)
                if msgInfo['status'] ==1 :
                    meterCode = msgInfo['addr']
                    varCode = msgInfo['itemCode']
                    valueStr = msgInfo['valueStr']
                    vk = f"{meterCode}_{varCode}"

                    if vk in self.info['variants'].keys():
                        varInfo = self.info['variants'][vk]
                        negativeFlag = varInfo['negative']
                        decSize = varInfo['decSize']
                        rate = varInfo['r1']
                        value = TUtils645.parse645Value(valueStr , negativeFlag, decSize, rate )
                        bucketCode = varInfo['sysCode']
                        self.kv.setValue(bucketCode , meterCode , varCode , value)
                    else:
                        print(f"var key error.")
        except Exception as er:
            self.manager.log(self , f"onMessage :{er}")

    def recMsgs(self ):
        try:
            pass
        except Exception as er:
            self.manager.log(self , er)
    def serviceHandler(self):
        try:
            super().serviceHandler()
            while self.running :
                try:
                    time.sleep(1)
                    self.sendMsgs()

                except Exception as erLoop:
                    self.manager.log(self , erLoop)
        except Exception as erBrfore:
            self.manager.log(self, erBrfore)
    def beforeStartService(self):
        try:
            super().beforeStartService()
            self.loadTask()
            self.subTopics = [ x['upTopic'] for x in self.info['dtus'].values() ]
        except Exception as er:
            self.manager.log(self, er)
    def startService(self):
        try:
            if not self.running:
                try:
                    self.beforeStartService()
                except Exception as erBrfore:
                    self.manager.log(self, erBrfore)
                self.serviceThread = threading.Thread(target=self.serviceHandler, daemon=True)
                self.running = True
                self.serviceThread.start()

                threading.Thread( target=self.start , daemon=True).start()
        except Exception as er:
            self.manager.log(self, er)
    def stopService(self):
        try:
            self.running = False
            self.stop()
        except Exception as er:
            self.manager.log(self, er)



manager.registCompType("TDtuMq645", TDtuMq645)